# 這是一個python3腳本

from smake_db import *
from Builder import *
from ConfigChecker import *
from Utility import *
from jsonc_parser.parser import JsoncParser
from multiprocessing import cpu_count
import os.path
import argparse
import sys
import logging
from smake_db import *
from Builder import *
from ConfigChecker import *
from Utility import *

SIMPLE_MAKE_VERSION         = 'v0.4.0'
BUILD_HISTORY_FILE_NAME     = '.build_history'
DEFAULT_OUTPUT_DIR          = 'output'
DEFAULT_CONF_FILE_NAME_1    = 'SimpleMake.jsonc'
DEFAULT_CONF_FILE_NAME_2    = 'SimpleMake.json'
COMPILATION_DB_FILE_NAME    = 'compilation_database.json'

# class SetEncoder(json.JSONEncoder):
#     def default(self, obj):
#         if isinstance(obj, set):
#             return list(obj)
#         return json.JSONEncoder.default(self, obj)

if __name__ == '__main__':
    # 检查命令行参数
    ap = argparse.ArgumentParser('SampleMake')
    # group = ap.add_mutually_exclusive_group()
    # group.add_argument('-p', '--project', required=False, default='', action='store', metavar='PROJ_NAME', help='build specific project only, ignore dependency')
    # ap.add_argument('--gen_compilation_database', required=False, default=False, action='store_true', help='generate compilation database json file in current directory')
    ap.add_argument('-o', '--output_dir', required=False, default=DEFAULT_OUTPUT_DIR, action='store', metavar='DIR', help='output directory')
    ap.add_argument('-f', '--conf_file', required=False, default='', action='store', metavar='FILE', help='conf file')
    ap.add_argument('--force_build', required=False, default=False, action='store_true', help='force build solution or project')
    ap.add_argument('--process_count', required=False, type=int, default=0, action='store', help='max process count for build')
    # ap.add_argument('-c', '--clean_obj', required=False, default=False, action='store_true', help='remove object directory in each project only')
    # ap.add_argument('--pre_build', required=False, default=False, action='store_true', help='run pre_build_solution_script only.')
    # ap.add_argument('--post_build', required=False, default=False, action='store_true', help='run post_build_solution_script only.')
    ap.add_argument('-C', '--clean_all', required=False, default=False, action='store_true', help='remove output directory')
    ap.add_argument('-v', '--version', required=False, default=False, action='store_true', help='show version')
    ap.add_argument('-d', '--debug', required=False, default=False, action='store_true', help='print debug info while building')
    args = ap.parse_args(sys.argv[1:])
    if args.process_count <= 0:
        args.process_count = cpu_count()
    if args.debug == True:
        logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(levelname)5s %(message)s')
    else:
        logging.basicConfig(level=logging.INFO, format='%(message)s')
    # if args.gen_compilation_database == True:
    #     # 需要所有文件的编译cmd，所以要设为强制
    #     args.force_build = True

    # 打印版本号
    if args.version == True:
        print('SimpleMake Version: ', SIMPLE_MAKE_VERSION)
        exit(0) 

    # 解析配置文件
    conf_file_name = ''
    if args.conf_file != '':
        conf_file_name = args.conf_file
        if os.path.exists(args.conf_file) == False:
            errorExit('conf file %s not exist.'%(args.conf_file))
    else:
        if os.path.exists(DEFAULT_CONF_FILE_NAME_1) == True:
            conf_file_name = DEFAULT_CONF_FILE_NAME_1
        elif os.path.exists(DEFAULT_CONF_FILE_NAME_2) == True:
            conf_file_name = DEFAULT_CONF_FILE_NAME_2
        else:
            errorExit('can not find conf file SimpleMake.json or SimpleMake.jsonc')
    smake_conf = JsoncParser.parse_file(conf_file_name)
    conf, err_msg = checkConf(smake_conf, '.')
    if err_msg != '':
        errorExit(err_msg)

    # 清理项目
    builder = Builder(smake_conf, args)
    if args.clean_all == True:
        builder.clean_all()
        exit(0)

    logging.info('SimpleMake ' + SIMPLE_MAKE_VERSION)
    logging.info('Output Directory   :  ' + args.output_dir)
    logging.info('Conf File          :  ' + args.conf_file)
    logging.info('Processor Count:     :  ' + str(args.process_count))

    # 生成所有构建用到的命令
    g_db.load(args.output_dir)
    build_cmds_info = builder.genBuildSolutionCmds()
    # if args.gen_compilation_database == True:
    #     pass
    # else:
    #     # 执行所有构建命令
    #     builder.build(build_cmds_info)
    builder.build(build_cmds_info)
    g_db.save()

    exit(0)

    # 生成compilation database
    if args.gen_compilation_database == True:
        db_info = []
        current_abs_path = os.path.abspath(os.getcwd())
        for build_info in all_projects_build_info:
            for cmd_info in build_info[1].compile:
                db_info.append({'directory':current_abs_path, 'command':cmd_info.cmd_str, 'file':cmd_info.src_file})
        f = open(COMPILATION_DB_FILE_NAME, "w")
        f.write(json.dumps(db_info, indent=4))
        f.close()
        print('\ngenerate compilation_database.json succeed')

